﻿#ifndef AaHeadCONFIG_H
#define AaHeadCONFIG_H

#include "configManager/configobject.h"
#include "configManager/configobjectarray.h"

class AACoreConfig : public ConfigObject
{
    Q_OBJECT
    Q_PROPERTY(int shotGlueDotTime READ shotGlueDotTime WRITE setShotGlueDotTime NOTIFY shotGlueDotTimeChanged)

    //Pattern Analysis Related

    Q_PROPERTY(int MaxIntensity READ MaxIntensity WRITE setMaxIntensity NOTIFY paramsChanged)
    Q_PROPERTY(int MinArea READ MinArea WRITE setMinArea NOTIFY paramsChanged)
    Q_PROPERTY(int MaxArea READ MaxArea WRITE setMaxArea NOTIFY paramsChanged)
    Q_PROPERTY(int SensorXRatio READ SensorXRatio WRITE setSensorXRatio NOTIFY paramsChanged)
    Q_PROPERTY(int SensorYRatio READ SensorYRatio WRITE setSensorYRatio NOTIFY paramsChanged)
    Q_PROPERTY(double EFL READ EFL WRITE setEFL NOTIFY paramsChanged)
    Q_PROPERTY(double FOVSlope READ FOVSlope WRITE setFOVSlope NOTIFY paramsChanged)
    Q_PROPERTY(double EstimatedAAFOV READ EstimatedAAFOV WRITE setEstimatedAAFOV NOTIFY paramsChanged)

    //AA Core Related
    Q_PROPERTY(int AASelectedLayer READ AASelectedLayer WRITE setAASelectedLayer NOTIFY paramsChanged)
    Q_PROPERTY(int Oversampling READ Oversampling WRITE setOversampling NOTIFY paramsChanged)
    Q_PROPERTY(int FitOrder READ FitOrder WRITE setFitOrder NOTIFY paramsChanged)
    Q_PROPERTY(int SampleFrequency READ SampleFrequency WRITE setSampleFrequency NOTIFY paramsChanged)

    //AA Analysis Related
    Q_PROPERTY(double aaAnalysisStartPos READ aaAnalysisStartPos WRITE setAAAnalysisStartPos NOTIFY paramsChanged)
    Q_PROPERTY(double aaAnalysisStepSize READ aaAnalysisStepSize WRITE setAAAnalysisStepSize NOTIFY paramsChanged)
    Q_PROPERTY(double aaAnalysisDelayInMs READ aaAnalysisDelayInMs WRITE setAAAnalysisDelayInMs NOTIFY paramsChanged)
    Q_PROPERTY(bool aaAnalysisTiltEnable READ aaAnalysisTiltEnable WRITE setAAAnalysisTiltEnable NOTIFY paramsChanged)
    Q_PROPERTY(int aaAnalysisCount READ aaAnalysisCount WRITE setAAAnalysisCount NOTIFY paramsChanged)

    Q_PROPERTY(bool aaCalibrationTiltNeedReverse READ aaCalibrationTiltNeedReverse WRITE setAACalibrationTiltNeedReverse NOTIFY paramsChanged)
    Q_PROPERTY(double aaCalibrationXTilt READ aaCalibrationXTilt WRITE setAACalibrationXTilt NOTIFY paramsChanged)
    Q_PROPERTY(int aaCalibrationXTiltMapping READ aaCalibrationXTiltMapping WRITE setAACalibrationXTiltMapping NOTIFY paramsChanged)
    Q_PROPERTY(double aaCalibrationYTilt READ aaCalibrationYTilt WRITE setAACalibrationYTilt NOTIFY paramsChanged)
    Q_PROPERTY(int aaCalibrationYTiltMapping READ aaCalibrationYTiltMapping WRITE setAACalibrationYTiltMapping NOTIFY paramsChanged)


    //Flowchart related

    Q_PROPERTY(QString currentFlowchartFilename READ currentFlowchartFilename WRITE setCurrentFlowchartFilename NOTIFY currentFlowchartFilenameParamsChanged)
    Q_PROPERTY(QString aaDebugImageFilename READ aaDebugImageFilename WRITE setAADebugImageFilename NOTIFY aaDebugImageFilenameParamsChanged)

    //Display Purpose
    Q_PROPERTY(int FontSizeDisplay READ FontSizeDisplay WRITE setFontSizeDisplay NOTIFY paramsChanged)

    //Ini Related
    Q_PROPERTY(QString sensorIniFilename READ sensorIniFilename WRITE setSensorIniFilename NOTIFY sensorIniFilenameParamsChanged)



public:
    AACoreConfig(QObject *parent = nullptr) :  ConfigObject(parent)
    {
        init();
    }

    int shotGlueDotTime() const
    {
        return m_shotGlueDotTime;
    }

    int MaxIntensity() const
    {
        return m_MaxIntensity;
    }

    int MinArea() const
    {
        return m_MinArea;
    }

    int MaxArea() const
    {
        return m_MaxArea;
    }

    int SensorXRatio() const
    {
        return m_SensorXRatio;
    }

    int SensorYRatio() const
    {
        return m_SensorYRatio;
    }

    QString currentFlowchartFilename() const
    {
        return m_currentFlowchartFilename;
    }

    QString aaDebugImageFilename() const
    {
        return m_aaDebugImageFilename;
    }

    int FontSizeDisplay() const
    {
        return m_FontSizeDisplay;
    }

    int FitOrder() const
    {
        return m_FitOrder;
    }

    int SampleFrequency() const
    {
        return m_SampleFrequency;
    }

    int AASelectedLayer() const
    {
        return m_AASelectedLayer;
    }

    QString sensorIniFilename() const
    {
        return m_sensorIniFilename;
    }

    int Oversampling() const
    {
        return m_Oversampling;
    }

    double aaAnalysisStartPos() const
    {
        return m_aaAnalysisStartPos;
    }

    double aaAnalysisStepSize() const
    {
        return m_aaAnalysisStepSize;
    }

    double aaAnalysisDelayInMs() const
    {
        return m_aaAnalysisDelayInMs;
    }

    bool aaAnalysisTiltEnable() const
    {
        return m_aaAnalysisTiltEnable;
    }

    int aaAnalysisCount() const
    {
        return m_aaAnalysisCount;
    }

    double aaCalibrationXTilt() const
    {
        return m_aaCalibrationXTilt;
    }

    int aaCalibrationXTiltMapping() const
    {
        return m_aaCalibrationXTiltMapping;
    }

    double aaCalibrationYTilt() const
    {
        return m_aaCalibrationYTilt;
    }

    int aaCalibrationYTiltMapping() const
    {
        return m_aaCalibrationXTiltMapping;
    }

    bool aaCalibrationTiltNeedReverse() const
    {
        return m_aaCalibrationTiltNeedReverse;
    }

    double EFL() const
    {
        return m_EFL;
    }

    double FOVSlope() const
    {
        return m_FOVSlope;
    }

    double EstimatedAAFOV() const
    {
        return m_EstimatedAAFOV;
    }

public slots:
    void setShotGlueDotTime(int shotGlueDotTime)
    {
        if (m_shotGlueDotTime == shotGlueDotTime)
            return;

        m_shotGlueDotTime = shotGlueDotTime;
        emit shotGlueDotTimeChanged(m_shotGlueDotTime);
    }

    void setMaxIntensity(int MaxIntensity)
    {
        if (m_MaxIntensity == MaxIntensity)
            return;

        m_MaxIntensity = MaxIntensity;
        emit paramsChanged(m_MaxIntensity);
    }

    void setMinArea(int MinArea)
    {
        if (m_MinArea == MinArea)
            return;

        m_MinArea = MinArea;
        emit paramsChanged(m_MinArea);
    }

    void setMaxArea(int MaxArea)
    {
        if (m_MaxArea == MaxArea)
            return;

        m_MaxArea = MaxArea;
        emit paramsChanged(m_MaxArea);
    }

    void setSensorXRatio(int SensorXRatio)
    {
        if (m_SensorXRatio == SensorXRatio)
            return;

        m_SensorXRatio = SensorXRatio;
        emit paramsChanged(m_SensorXRatio);
    }

    void setSensorYRatio(int SensorYRatio)
    {
        if (m_SensorYRatio == SensorYRatio)
            return;

        m_SensorYRatio = SensorYRatio;
        emit paramsChanged(m_SensorYRatio);
    }


    void setCurrentFlowchartFilename(QString currentFlowchartFilename)
    {
        if (m_currentFlowchartFilename == currentFlowchartFilename)
            return;

        m_currentFlowchartFilename = currentFlowchartFilename;
        emit currentFlowchartFilenameParamsChanged(m_currentFlowchartFilename);
    }

    void setAADebugImageFilename(QString aaDebugImageFilename)
    {
        if (m_aaDebugImageFilename == aaDebugImageFilename)
            return;

        m_aaDebugImageFilename = aaDebugImageFilename;
        emit aaDebugImageFilenameParamsChanged(m_aaDebugImageFilename);
    }

    void setFontSizeDisplay(int FontSizeDisplay)
    {
        if (m_FontSizeDisplay == FontSizeDisplay)
            return;

        m_FontSizeDisplay = FontSizeDisplay;
        emit paramsChanged(m_FontSizeDisplay);
    }

    void setFitOrder(int FitOrder)
    {
        if (m_FitOrder == FitOrder)
            return;

        m_FitOrder = FitOrder;
        emit paramsChanged(m_FitOrder);
    }

    void setSampleFrequency(int SampleFrequency)
    {
        if (m_SampleFrequency == SampleFrequency)
            return;

        m_SampleFrequency = SampleFrequency;
        emit paramsChanged(m_SampleFrequency);
    }

    void setAASelectedLayer(int AASelectedLayer)
    {
        if (m_AASelectedLayer == AASelectedLayer)
            return;

        m_AASelectedLayer = AASelectedLayer;
        emit paramsChanged(m_AASelectedLayer);
    }

    void setSensorIniFilename(QString sensorIniFilename)
    {
        if (m_sensorIniFilename == sensorIniFilename)
            return;

        m_sensorIniFilename = sensorIniFilename;
        emit sensorIniFilenameParamsChanged(m_sensorIniFilename);
    }

    void setOversampling(int Oversampling)
    {
        if (m_Oversampling == Oversampling)
            return;

        m_Oversampling = Oversampling;
        emit paramsChanged(m_Oversampling);
    }

    void setAAAnalysisStartPos(double aaAnalysisStartPos)
    {
        if (qFuzzyCompare(m_aaAnalysisStartPos, aaAnalysisStartPos))
            return;

        m_aaAnalysisStartPos = aaAnalysisStartPos;
        emit paramsChanged(m_aaAnalysisStartPos);
    }

    void setAAAnalysisStepSize(double aaAnalysisStepSize)
    {
        if (qFuzzyCompare(m_aaAnalysisStepSize, aaAnalysisStepSize))
            return;

        m_aaAnalysisStepSize = aaAnalysisStepSize;
        emit paramsChanged(m_aaAnalysisStepSize);
    }

    void setAAAnalysisDelayInMs(double aaAnalysisDelayInMs)
    {
        if (qFuzzyCompare(m_aaAnalysisDelayInMs, aaAnalysisDelayInMs))
            return;

        m_aaAnalysisDelayInMs = aaAnalysisDelayInMs;
        emit paramsChanged(m_aaAnalysisDelayInMs);
    }

    void setAAAnalysisTiltEnable(bool aaAnalysisTiltEnable)
    {
        if (m_aaAnalysisTiltEnable == aaAnalysisTiltEnable)
            return;

        m_aaAnalysisTiltEnable = aaAnalysisTiltEnable;
        emit paramsChanged(m_aaAnalysisTiltEnable);
    }

    void setAAAnalysisCount(int aaAnalysisCount)
    {
        if (m_aaAnalysisCount == aaAnalysisCount)
            return;

        m_aaAnalysisCount = aaAnalysisCount;
        emit paramsChanged(m_aaAnalysisCount);
    }

    void aaCalibrationXTiltMapping(int aaCalibrationXTiltMapping)
    {
        if (m_aaCalibrationXTiltMapping == aaCalibrationXTiltMapping)
            return;

        m_aaCalibrationXTiltMapping = aaCalibrationXTiltMapping;
        emit paramsChanged(m_aaCalibrationXTiltMapping);
    }

    void aaCalibrationYTiltMapping(int aaCalibrationXTiltMapping)
    {
        if (m_aaCalibrationXTiltMapping == aaCalibrationXTiltMapping)
            return;

        m_aaCalibrationXTiltMapping = aaCalibrationXTiltMapping;
        emit paramsChanged(m_aaCalibrationXTiltMapping);
    }

    void setAACalibrationXTilt(double aaCalibrationXTilt)
    {
        if (qFuzzyCompare(m_aaCalibrationXTilt, aaCalibrationXTilt))
            return;

        m_aaCalibrationXTilt = aaCalibrationXTilt;
        emit paramsChanged(m_aaCalibrationXTilt);
    }

    void setAACalibrationXTiltMapping(int aaCalibrationXTiltMapping)
    {
        if (m_aaCalibrationXTiltMapping == aaCalibrationXTiltMapping)
            return;

        m_aaCalibrationXTiltMapping = aaCalibrationXTiltMapping;
        emit paramsChanged(m_aaCalibrationXTiltMapping);
    }

    void setAACalibrationYTiltMapping(int aaCalibrationYTiltMapping)
    {
        if (m_aaCalibrationYTiltMapping == aaCalibrationYTiltMapping)
            return;

        m_aaCalibrationYTiltMapping = aaCalibrationYTiltMapping;
        emit paramsChanged(m_aaCalibrationYTiltMapping);
    }

    void setAACalibrationYTilt(double aaCalibrationYTilt)
    {
        if (qFuzzyCompare(m_aaCalibrationYTilt, aaCalibrationYTilt))
            return;

        m_aaCalibrationYTilt = aaCalibrationYTilt;
        emit paramsChanged(m_aaCalibrationYTilt);
    }

    void setAACalibrationTiltNeedReverse(bool aaCalibrationTiltNeedReverse)
    {
        if (m_aaCalibrationTiltNeedReverse == aaCalibrationTiltNeedReverse)
            return;

        m_aaCalibrationTiltNeedReverse = aaCalibrationTiltNeedReverse;
        emit paramsChanged(m_aaCalibrationTiltNeedReverse);
    }

    void setEFL(double EFL)
    {
        qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_EFL, EFL))
            return;

        m_EFL = EFL;
        emit paramsChanged(m_EFL);
    }

    void setFOVSlope(double FOVSlope)
    {
        qWarning("Floating point comparison needs context sanity check");
        if (qFuzzyCompare(m_FOVSlope, FOVSlope))
            return;

        m_FOVSlope = FOVSlope;
        emit paramsChanged(m_FOVSlope);
    }

    void setEstimatedAAFOV(double EstimatedAAFOV)
    {
        if (m_EstimatedAAFOV == EstimatedAAFOV)
            return;

        m_EstimatedAAFOV = EstimatedAAFOV;
        emit paramsChanged(m_EstimatedAAFOV);
    }

signals:
    void shotGlueDotTimeChanged(int shotGlueDotTime);

    void paramsChanged(int MaxIntensity);

    void currentFlowchartFilenameParamsChanged(QString currentFlowchartFilename);

    void aaDebugImageFilenameParamsChanged(QString aaDebugImageFilename);

    void sensorIniFilenameParamsChanged(QString sensorIniFilename);

private:

    int m_shotGlueDotTime = 99;
    int m_MaxIntensity = 60;
    int m_MinArea = 500;
    int m_MaxArea = 3000;
    int m_SensorXRatio = 630;
    int m_SensorYRatio = 610;
    QString m_currentFlowchartFilename = "";
    QString m_aaDebugImageFilename;
    int m_FontSizeDisplay = 15;
    int m_FitOrder = 4;
    int m_SampleFrequency = 0;
    int m_AASelectedLayer = 0;
    QString m_sensorIniFilename = "";
    int m_Oversampling = 1;
    double m_aaAnalysisStartPos = 0;
    double m_aaAnalysisStepSize = 10;
    double m_aaAnalysisDelayInMs = 300;
    bool m_aaAnalysisTiltEnable = false;
    int m_aaAnalysisCount = 7;
    double m_aaCalibrationXTilt = 1;
    int m_aaCalibrationXTiltMapping = 0;
    double m_aaCalibrationYTilt = 1;
    int m_aaCalibrationYTiltMapping = 0;
    bool m_aaCalibrationTiltNeedReverse = false;
    double m_EFL = 1;
    double m_FOVSlope = 1;
    double m_EstimatedAAFOV = 1;
};

#endif // AaHeadCONFIG_H
